package com.yuhang.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuhang.demo.dto.request.DrugRelationAddRequest;
import com.yuhang.demo.dto.request.DrugRelationUpdateRequest;
import com.yuhang.demo.dto.response.PageResult;
import com.yuhang.demo.dto.response.Result;
import com.yuhang.demo.entity.RuleDrugRelation;
import com.yuhang.demo.entity.RuleInfo;
import com.yuhang.demo.mapper.RuleDrugRelationMapper;
import com.yuhang.demo.service.RuleDrugRelationService;
import com.yuhang.demo.service.RuleInfoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class RuleDrugRelationServiceImpl extends ServiceImpl<RuleDrugRelationMapper, RuleDrugRelation> implements RuleDrugRelationService {

    @Autowired
    private RuleDrugRelationMapper drugRelationMapper;

    @Lazy
    @Autowired
    private RuleInfoService ruleInfoService;

    public RuleDrugRelationServiceImpl(RuleDrugRelationMapper drugRelationMapper, RuleInfoService ruleInfoService) {
        this.drugRelationMapper = drugRelationMapper;
        this.ruleInfoService = ruleInfoService;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Long> addDrugRelation(DrugRelationAddRequest request) {
        // 1. 校验规则是否存在
        Result<RuleInfo> ruleResult = ruleInfoService.getRuleById(request.getRuleId());
        if (ruleResult.getCode() != 200) {
            return Result.fail(404, "所属规则不存在");
        }

        // 2. 校验药品代码是否重复（同一规则下药品代码唯一）
        LambdaQueryWrapper<RuleDrugRelation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RuleDrugRelation::getRuleId, request.getRuleId())
                .eq(RuleDrugRelation::getDrugCode, request.getDrugCode());
        if (drugRelationMapper.selectCount(wrapper) > 0) {
            return Result.fail(400, "该规则下已存在此药品代码，不可重复添加");
        }

        // 3. 封装药品关联实体
        RuleDrugRelation drugRelation = new RuleDrugRelation();
        BeanUtils.copyProperties(request, drugRelation);

        // 4. 插入数据库
        drugRelationMapper.insert(drugRelation);

        // 5. 更新规则的药品代码数量（+1）
        RuleInfo ruleInfo = ruleResult.getData();
        ruleInfo.setDrugCodeCount(ruleInfo.getDrugCodeCount() + 1);
        ruleInfoService.updateById(ruleInfo);

        return Result.success(drugRelation.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> updateDrugRelation(DrugRelationUpdateRequest request) {
        // 1. 校验药品关联是否存在
        RuleDrugRelation existRelation = drugRelationMapper.selectById(request.getId());
        if (existRelation == null) {
            return Result.fail(404, "药品关联不存在");
        }

        // 2. 若修改药品代码，校验是否重复
        if (!existRelation.getDrugCode().equals(request.getDrugCode())) {
            LambdaQueryWrapper<RuleDrugRelation> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(RuleDrugRelation::getRuleId, existRelation.getRuleId())
                    .eq(RuleDrugRelation::getDrugCode, request.getDrugCode())
                    .ne(RuleDrugRelation::getId, request.getId());
            if (drugRelationMapper.selectCount(wrapper) > 0) {
                return Result.fail(400, "该规则下已存在此药品代码，不可重复");
            }
        }

        // 3. 封装更新数据
        RuleDrugRelation updateRelation = new RuleDrugRelation();
        BeanUtils.copyProperties(request, updateRelation);

        // 4. 执行更新
        drugRelationMapper.updateById(updateRelation);
        return Result.success(true);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> deleteDrugRelation(Long id) {
        // 1. 校验药品关联是否存在
        RuleDrugRelation existRelation = drugRelationMapper.selectById(id);
        if (existRelation == null) {
            return Result.fail(404, "药品关联不存在");
        }

        // 2. 逻辑删除药品关联
        drugRelationMapper.deleteById(id);

        // 3. 更新规则的药品代码数量（-1）
        RuleInfo ruleInfo = ruleInfoService.getById(existRelation.getRuleId());
        ruleInfo.setDrugCodeCount(Math.max(0, ruleInfo.getDrugCodeCount() - 1));
        ruleInfoService.updateById(ruleInfo);

        return Result.success(true);
    }

    @Override
    public Result<PageResult<RuleDrugRelation>> getDrugRelationPage(Long ruleId, Integer pageNum, Integer pageSize) {
        // 1. 校验规则是否存在
        Result<RuleInfo> ruleResult = ruleInfoService.getRuleById(ruleId);
        if (ruleResult.getCode() != 200) {
            return Result.fail(404, "所属规则不存在");
        }

        // 2. 分页查询
        Page<RuleDrugRelation> page = new Page<>(pageNum, pageSize);
        Page<RuleDrugRelation> relationPage = (Page<RuleDrugRelation>) drugRelationMapper.selectByRuleIdPage(page, ruleId);

        // 3. 封装分页结果
        PageResult<RuleDrugRelation> pageResult = new PageResult<>();
        pageResult.setTotal(relationPage.getTotal());
        pageResult.setPages(relationPage.getPages());
        pageResult.setRecords(relationPage.getRecords());
        pageResult.setCurrent(pageNum);
        pageResult.setSize(pageSize);

        return Result.success(pageResult);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByRuleId(Long ruleId) {
        // 1. 批量删除指定规则的所有药品关联
        LambdaQueryWrapper<RuleDrugRelation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RuleDrugRelation::getRuleId, ruleId);
        drugRelationMapper.delete(wrapper);

        // 2. 重置规则的药品代码数量为0
        RuleInfo ruleInfo = ruleInfoService.getById(ruleId);
        if (ruleInfo != null) {
            ruleInfo.setDrugCodeCount(0);
            ruleInfoService.updateById(ruleInfo);
        }
    }
}
